The continuous expansion of the Internet, the expansion and sophistication of enterprise computing networks and systems, the proliferation of content stored and accessible over the Internet, and numerous other factors continue to drive the need for large sophisticated data storage systems. Consequently, as the demand for data storage continues to increase, larger and more sophisticated storage systems are being designed and deployed. Many large scale data storage systems utilize storage appliances that include arrays of storage media. Typically, these storage systems include a file system for storing and accessing files. In addition to storing system files (e.g., operating system files, device driver files, etc.), the file system provides storage and access of user data files. For a user to access a file, one or more input/output (I/O) requests are generated to retrieve data blocks associated with the file. Any time an I/O operation is performed, a processing speed of the storage system is impacted as the requested data is retrieved from the storage media. Depending on a type of storage media storing the requested data, there is an increased latency in fulfilling an I/O request. For example, retrieving data from cache memory is faster than retrieving data from random access memory (RAM), which is faster than retrieving data from persistent storage media, such as spinning disks.
Reading data asynchronously from the persistent storage media generally decreases latency. However, some storage devices utilize virtual storage with a hierarchical system for storing data blocks with one or more levels of indirect blocks (metadata) pointing to direct blocks of data stored on persistent storage media. The indirect blocks of data are stored on the persistent storage media separate from the direct blocks. Thus, conventional storage devices require all relevant indirect blocks to be read prior to issuing an asynchronous request, thereby requiring a synchronous read of the indirect blocks during the asynchronous operation and incurring an overhead. Stated differently, to read a block of data, the location of the data must first be ascertained using the indirect block. If the block location is not already read into cache memory, it must first be read into cache memory from the persistent storage media, which incurs synchronous read overhead. Where data is stored with multiple levels of indirect blocks, for example, in a sorted tree structure, there may be multiple synchronous reads of the indirect blocks as the sorted tree is traversed to reach the data block that is the target of the asynchronous read request. Waiting for all the metadata to be accumulated synchronously prior to issuing an asynchronous read impacts performance and increases latency, as the read request is locked until the metadata is accumulated.
It is with these observations in mind, among others, that various aspects of the present disclosure were conceived and developed.